package crew.blt.handsound.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

import crew.blt.handsound.client.mvc.controller.IMainController;
import crew.blt.handsound.client.mvc.controller.MainController;
import crew.blt.handsound.client.mvc.view.SitePage;
import crew.blt.handsound.client.services.user.UserService;
import crew.blt.handsound.client.services.user.UserServiceAsync;
import crew.blt.handsound.client.widgets.login.LoginPanel;
import crew.blt.handsound.shared.domain.Auth;
import crew.blt.handsound.shared.domain.AuthType;
import crew.blt.handsound.shared.domain.User;
import crew.gwt.client.services.util.ServerCall;

public class Framework implements ValueChangeHandler<String> {

	public static String APPLICAITON_NAME = "mine";
	
	/*
	 * Singleton
	 */
	private static Framework instance = new Framework();
	public static Framework get() {
		return instance;
	}

	private User user;
	
	/**
	 * Constructor for initialising the singleton Framework instance
	 */
	private Framework(){
		initLoginRequestCommand();
		initHistoryStuff();
	}

	public void load(){
		setUser();
	}
	
	private void initHistoryStuff() {
		GWT.log("Add framework history handler");
		History.addValueChangeHandler(this);
	}

	private void initLoginRequestCommand() {
		GWT.log("Injecting login request command");
		ServerCall.setLoginRequestCommand(LoginPanel.cmdOfferLoginPopup);
	}
	

	//-------------------------------------------------------------
	//------------------------ Manage history
	
	@Override
	public void onValueChange(ValueChangeEvent<String> event) {
		final String pageToReach = History.getToken().split("__")[0];
		if(pageToReach.equals("")){
			MainController.getInstance().onPageRequest(SitePage.HOME);
		}
		if(pageToReach.equals("logout")){
			redirectNativeByReplace("/"+APPLICAITON_NAME+"/logout");
		}
		for(SitePage page : SitePage.values()){
			if(pageToReach.equals(page.location)){
				MainController.getInstance().onPageRequest(page);
			}
		}
	}
	
	public void setLocation(String token){
		History.newItem(token,false);
	}

	//-------------------------------------------------------------
	//------------------------ Functionality
	
	public boolean isAuth(){
		return (getUser()==null)? false:true;
	}
	
	private static void redirectByHistory(String url){
		History.newItem(url);
	}

	public void redirectByReplace(String url) {
		redirectNativeByReplace("/"+APPLICAITON_NAME+".html?gwt.codesvr=127.0.0.1:9997#"+url);
//		redirectNativeByReplace("/"+APPLICAITON_NAME+"/"+APPLICAITON_NAME+".html#"+url); //mode prod
	};
	
	public native void redirectNativeByReplace(String url) /*-{
	    $wnd.location.replace(url);
	}-*/;
	
	public native void reloadModule() /*-{ 
        $wnd.location.reload(); 
    }-*/; 
	
	//-------------------------------------------------------------
	//------------------------ Manage user
	
	public void setUser() {
		final UserServiceAsync loginService = GWT.create(UserService.class);
		new ServerCall<User>(){
			@Override
			protected void callService(AsyncCallback<User> asyncCallback) {
				loginService.login(asyncCallback);
			}
			@Override
			public void onSuccess(User result) {
				setUser(result);
			}
		}.call();
	}
	public void setUser(final String username){
		final UserServiceAsync userService = GWT.create(UserService.class);
		new ServerCall<User>(){
			@Override
			protected void callService(AsyncCallback<User> asyncCallback) {
				userService.getUser(username, asyncCallback);
			}
			@Override
			public void onSuccess(User result) {
				setUser(result);
			}
		}.call();
	}

	private void setUser(User newUser){
		IMainController c = MainController.getInstance();
		c.onUserChange(newUser);
		History.fireCurrentHistoryState();
	}
	
	public User getUser() {
		return user;
	}

	public String getUrlArgs() {
		String[] args = History.getToken().split("__");
		if(args.length>1)
			return "__"+args[1];
		return "";
	}
}
